
#!/bin/bash
# Linux等保3.0加固与检测脚本
# 版本: 1.0
# 作者: jokr
# 日期: 2025年6月10日
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
# 检查是否为root用户
if [ "$(id -u)" -ne 0 ]; then
    echo -e "${RED}错误: 此脚本必须以root用户身份运行${NC}"
    exit 1
fi
# 日志文件
LOG_FILE="/var/log/CPS30_$(date +%Y%m%d).log"
touch $LOG_FILE
# 记录函数
log() {
    echo -e "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}
# 1. 身份鉴别加固
harden_auth() {
    log "开始身份鉴别加固..."
    # 密码复杂度设置
    if [ -f /etc/pam.d/system-auth ]; then
        grep -q "pam_pwquality.so" /etc/pam.d/system-auth
        if [ $? -ne 0 ]; then
            sed -i '/password\s*requisite\s*pam_pwquality.so/c password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type= minlen=8 lcredit=-1 ucredit=-1 dcredit=-1 ocredit=-1 enforce_for_root' /etc/pam.d/system-auth
            log "密码复杂度策略已配置"
        else
            log "密码复杂度策略已存在，跳过"
        fi
    fi
    # 密码有效期设置
    sed -i '/^PASS_MAX_DAYS/c PASS_MAX_DAYS   90' /etc/login.defs
    sed -i '/^PASS_MIN_DAYS/c PASS_MIN_DAYS   1' /etc/login.defs
    sed -i '/^PASS_WARN_AGE/c PASS_WARN_AGE   7' /etc/login.defs
    log "密码有效期已设置为90天"
    # 检查空密码账户
    empty_passwd=$(awk -F: '($2 == "") {print $1}' /etc/shadow)
    if [ -n "$empty_passwd" ]; then
        log "${YELLOW}警告: 发现空密码账户: $empty_passwd${NC}"
    fi
    # 锁定不必要的账户
    for user in lp sync shutdown halt ftp news uucp operator games gopher; do
        if id -u $user >/dev/null 2>&1; then
            usermod -L $user
            log "已锁定账户: $user"
        fi
    done
    # SSH配置加固
    if [ -f /etc/ssh/sshd_config ]; then
        cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
        sed -i '/^#PermitRootLogin/c PermitRootLogin no' /etc/ssh/sshd_config
        sed -i '/^#ClientAliveInterval/c ClientAliveInterval 600' /etc/ssh/sshd_config
        sed -i '/^#ClientAliveCountMax/c ClientAliveCountMax 0' /etc/ssh/sshd_config
        sed -i '/^#Protocol/c Protocol 2' /etc/ssh/sshd_config
        sed -i '/^#LogLevel/c LogLevel VERBOSE' /etc/ssh/sshd_config
        sed -i '/^#MaxAuthTries/c MaxAuthTries 3' /etc/ssh/sshd_config
        sed -i '/^#LoginGraceTime/c LoginGraceTime 60' /etc/ssh/sshd_config
        systemctl restart sshd
        log "SSH配置已加固"
    fi
    log "身份鉴别加固完成"
}
# 2. 访问控制加固
harden_access() {
    log "开始访问控制加固..."
    # 文件权限检查
    for file in /etc/passwd /etc/shadow /etc/group /etc/gshadow; do
        if [ -f "$file" ]; then
            chmod 644 /etc/passwd
            chmod 600 /etc/shadow
            chmod 644 /etc/group
            chmod 600 /etc/gshadow
            log "关键文件权限已设置"
            break
        fi
    done
    # 限制su命令使用
    if grep -q '^auth\s*required\s*pam_wheel.so' /etc/pam.d/su; then
        sed -i '/^auth\s*required\s*pam_wheel.so/c auth required pam_wheel.so group=wheel' /etc/pam.d/su
    else
        echo "auth required pam_wheel.so group=wheel" >> /etc/pam.d/su
    fi
    log "su命令限制已配置"
    # 禁用不必要的服务
    for service in telnet rsh rlogin ypbind tftp sendmail ident; do
        if systemctl is-enabled $service >/dev/null 2>&1; then
            systemctl disable $service
            systemctl stop $service
            log "已禁用服务: $service"
        fi
    done
    log "访问控制加固完成"
}
# 3. 安全审计加固
harden_audit() {
    log "开始安全审计加固..."
    # 安装auditd
    if ! command -v auditctl >/dev/null 2>&1; then
        if command -v yum >/dev/null 2>&1; then
            yum install -y audit
        elif command -v apt-get >/dev/null 2>&1; then
            apt-get install -y auditd
        fi
    fi
    # 配置auditd规则
    if [ -f /etc/audit/audit.rules ]; then
        cat > /etc/audit/audit.rules <<EOF
# 记录系统调用
-a always,exit -F arch=b64 -S adjtimex -S settimeofday -k time-change
-a always,exit -F arch=b32 -S adjtimex -S settimeofday -S stime -k time-change
-a always,exit -F arch=b64 -S clock_settime -k time-change
-a always,exit -F arch=b32 -S clock_settime -k time-change
-a always,exit -F arch=b64 -S sethostname -S setdomainname -k system-locale
-a always,exit -F arch=b32 -S sethostname -S setdomainname -k system-locale
-a always,exit -F arch=b64 -S open -F a1&03 -F path=/etc/passwd -k identity
-a always,exit -F arch=b32 -S open -F a1&03 -F path=/etc/passwd -k identity
# 记录关键文件修改
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/sudoers -p wa -k scope
-w /var/log/faillog -p wa -k logins
-w /var/log/lastlog -p wa -k logins
-w /var/run/utmp -p wa -k session
-w /var/log/wtmp -p wa -k session
-w /var/log/btmp -p wa -k session
# 记录特权命令使用
-w /bin/su -p x -k privileged
-w /usr/bin/sudo -p x -k privileged
EOF
        systemctl enable auditd
        systemctl restart auditd
        log "auditd审计规则已配置"
    fi
    # 配置rsyslog
    if [ -f /etc/rsyslog.conf ]; then
        sed -i '/^auth,authpriv.*/c auth,authpriv.* /var/log/auth.log' /etc/rsyslog.conf
        systemctl restart rsyslog
        log "rsyslog配置已更新"
    fi
    log "安全审计加固完成"
}
# 4. 入侵防范加固
harden_intrusion() {
    log "开始入侵防范加固..."
    # 配置防火墙
    if command -v ufw >/dev/null 2>&1; then
        ufw enable
        ufw default deny
        log "UFW防火墙已启用"
    elif command -v firewall-cmd >/dev/null 2>&1; then
        systemctl enable firewalld
        systemctl start firewalld
        firewall-cmd --set-default-zone=drop
        firewall-cmd --runtime-to-permanent
        log "firewalld已启用"
    fi
    # 启用SYN cookies
    echo 1 > /proc/sys/net/ipv4/tcp_syncookies
    echo "net.ipv4.tcp_syncookies = 1" >> /etc/sysctl.conf
    # 禁用ICMP重定向
    echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
    echo "net.ipv4.conf.all.accept_redirects = 0" >> /etc/sysctl.conf
    # 禁用IP转发
    echo 0 > /proc/sys/net/ipv4/ip_forward
    echo "net.ipv4.ip_forward = 0" >> /etc/sysctl.conf
    sysctl -p
    log "内核参数已加固"
    log "入侵防范加固完成"
}
# 5. 资源控制加固
harden_resource() {
    log "开始资源控制加固..."
    # 配置limits.conf
    if [ -f /etc/security/limits.conf ]; then
        echo "* hard core 0" >> /etc/security/limits.conf
        echo "* hard rss 5000" >> /etc/security/limits.conf
        echo "* hard nproc 50" >> /etc/security/limits.conf
        log "资源限制已配置"
    fi
    # 禁用core dump
    echo "* hard core 0" >> /etc/security/limits.conf
    echo "fs.suid_dumpable = 0" >> /etc/sysctl.conf
    sysctl -p
    log "资源控制加固完成"
}
# 检测函数
check_compliance() {
    log "开始等保3.0合规性检测..."
    # 1. 身份鉴别检测
    log "=== 身份鉴别检测 ==="
    # 密码复杂度检测
    if [ -f /etc/pam.d/system-auth ]; then
        grep -q "minlen=8" /etc/pam.d/system-auth
        if [ $? -eq 0 ]; then
            log "${GREEN}密码复杂度策略符合要求${NC}"
        else
            log "${RED}密码复杂度策略不符合要求${NC}"
        fi
    fi
    # 密码有效期检测
    pass_max_days=$(grep '^PASS_MAX_DAYS' /etc/login.defs | awk '{print $2}')
    if [ "$pass_max_days" -le 90 ]; then
        log "${GREEN}密码有效期设置符合要求 (${pass_max_days}天)${NC}"
    else
        log "${RED}密码有效期设置不符合要求 (${pass_max_days}天)${NC}"
    fi
    # 检查root远程登录
    if [ -f /etc/ssh/sshd_config ]; then
        permit_root=$(grep '^PermitRootLogin' /etc/ssh/sshd_config | awk '{print $2}')
        if [ "$permit_root" == "no" ]; then
            log "${GREEN}SSH root登录已禁用${NC}"
        else
            log "${RED}SSH root登录未禁用${NC}"
        fi
    fi
    # 2. 访问控制检测
    log "=== 访问控制检测 ==="
    # 检查关键文件权限
    passwd_perm=$(stat -c %a /etc/passwd)
    shadow_perm=$(stat -c %a /etc/shadow)
    if [ "$passwd_perm" -eq 644 ] && [ "$shadow_perm" -eq 600 ]; then
        log "${GREEN}关键文件权限符合要求${NC}"
    else
        log "${RED}关键文件权限不符合要求 (passwd: ${passwd_perm}, shadow: ${shadow_perm})${NC}"
    fi
    # 3. 安全审计检测
    log "=== 安全审计检测 ==="
    # 检查auditd是否运行
    if systemctl is-active auditd >/dev/null 2>&1; then
        log "${GREEN}auditd服务正在运行${NC}"
    else
        log "${RED}auditd服务未运行${NC}"
    fi
    # 4. 入侵防范检测
    log "=== 入侵防范检测 ==="
    # 检查防火墙状态
    if command -v ufw >/dev/null 2>&1; then
        if ufw status | grep -q "Status: active"; then
            log "${GREEN}UFW防火墙已启用${NC}"
        else
            log "${RED}UFW防火墙未启用${NC}"
        fi
    elif command -v firewall-cmd >/dev/null 2>&1; then
        if systemctl is-active firewalld >/dev/null 2>&1; then
            log "${GREEN}firewalld已启用${NC}"
        else
            log "${RED}firewalld未启用${NC}"
        fi
    else
        log "${YELLOW}未检测到防火墙服务${NC}"
    fi
    # 5. 资源控制检测
    log "=== 资源控制检测 ==="
    # 检查core dump设置
    suid_dumpable=$(sysctl -n fs.suid_dumpable)
    if [ "$suid_dumpable" -eq 0 ]; then
        log "${GREEN}core dump设置符合要求${NC}"
    else
        log "${RED}core dump设置不符合要求 (当前值: ${suid_dumpable})${NC}"
    fi
    log "等保3.0合规性检测完成"
}
# 主菜单
main_menu() {
    echo -e "\nLinux等保3.0加固与检测脚本"
    echo "1. 执行等保加固"
    echo "2. 执行合规性检测"
    echo "3. 执行加固和检测"
    echo "4. 退出"
    read -p "请选择操作 (1-4): " choice
    case $choice in
        1)
            harden_auth
            harden_access
            harden_audit
            harden_intrusion
            harden_resource
            ;;
        2)
            check_compliance
            ;;
        3)
            harden_auth
            harden_access
            harden_audit
            harden_intrusion
            harden_resource
            check_compliance
            ;;
        4)
            exit 0
            ;;
        *)
            echo -e "${RED}无效的选择${NC}"
            main_menu
            ;;
    esac
}
# 执行主菜单
main_menu
